iT邦幫忙

2024 iThome 鐵人賽

DAY 27
0
佛心分享-IT 人自學之術

ASP.NET Core 30日成長路系列 第 27

Day27:Entity Framework Core常見語法介紹

  • 分享至 

  • xImage
  •  

Entity Framework Core常見語法介紹


今天要來學的是EF Core中常見的語法們~想知道怎麼查EF Core資料庫看這篇就對惹✨

❇️無條件查詢所有資料
以下是查詢Products、Employees、Orders所有資料的語法,也列出了同步及非同步兩種形式,而在.NET(Core)中建議以非同步為主。

🔗Controller/ProductsController.cs

public async Task<IActionResult> QueryAllData()
{
    // Asynchronous
    List<Products> products = await _context.Products.ToListAsync();
    var employees = await _context.Employees.ToListAsync();

    // Synchronous
    List<Orders> orders = _context.Orders.ToList();
    var orderDetails = _context.OrderDetails.ToList();

    return View(employees);
}

❇️用First和Single方法查詢單一筆資料
First()、FirstOrDefault()、Single()、SingleOrDefault()四個方法皆是回傳同一筆資料,但有差異,差異如下表:
https://ithelp.ithome.com.tw/upload/images/20241011/20167550uLYXrkmceG.png

💡First與Single方法回傳之比較
在資料來源不為null,且含有資料成員的情況下,以下是first與FirstOrDefault方法之比較⬇️
1.回傳序列有一或多筆資料:First與FirstOrDefault皆回傳第一筆資料。
2.回傳序列無資料:
First方法➡️擲出InvalidOperationException例外
FirstOrDefault方法➡️回傳預設值

Single與SingleOrDefault方法之比較⬇️
1.回傳序列只有一筆資料:Single與SingleOrDefault皆回傳該筆唯一資料。
2.回傳序列有多筆資料:Single與SingleOrDefault皆會擲出InvalidOperationException例外。
3.回傳序列若無資料:
Single方法➡️擲出InvalidOperationException例外
SingleOrDefault方法➡️回傳預設值

❇️以特定條件查詢資料
在Where中以特定條件查詢、排序,同時列出Query Syntax與Method Query兩種查詢方法。
🔗Controller/ProductsController.cs

public async Task<IActionResult> FilteringData()
{
    // Query Syntax 查詢語法
    var p1 = await (from p in _context.Products
                    where p.UnitPrice >= 10 && p.UnitPrice <= 15
                    orderby p.ProductName, p.UnitPrice
                    select p).ToListAsync();
                    
    // Method Syntax 方法語法
    var p2 = await _context.Products
        .Where(p => p.UnitPrice >= 10 && p.UnitPrice <= 15)
        .OrderBy(p => p.ProductName)
        .ThenBy(p => p.UnitPrice)
        .ToListAsync(); 

    // 同步查詢語法
    var p3 = (from p in _context.Products
              where p.UnitPrice >= 10 && p.UnitPrice < 15
              orderby p.ProductName descending, p.UnitPrice ascending
              select p).ToList(); 

    // 使用 AsEnumerable() 來轉換成 IEnumerable<Product>
    var p4 = _context.Products
        .AsEnumerable()
        .Where(p => p.UnitPrice >= 10 && p.UnitPrice <= 15)
        .OrderByDescending(p => p.ProductName)
        .ThenByDescending(p => p.UnitPrice)
        .ToList(); 

    // 使用 AsQueryable() 來轉換成 IQueryable<Product>
    var p5 = _context.Products
        .AsQueryable()
        .Where(p => p.UnitPrice >= 10 && p.UnitPrice <= 15)
        .OrderByDescending(p => p.ProductName)
        .ThenByDescending(p => p.UnitPrice)
        .ToList(); // 匿名排序

    return View(p1); // 回傳 p1 給 View
}

❇️多個資料表的Inner Join查詢
前面所談的都是針對單一資料表,但真的在使用上一般都是多個資料表間的關聯查詢。
以下是Inner Join查詢語法⬇️

public async Task<IActionResult> TablesJoin()
{
//1. 兩表聯合查詢 - 匿名示例
var innerJoin1 = from cate in _context.Categories
join prod in _context.Products on cate.CategoryId equals prod.CategoryId
select new { Name = prod.ProductName, Category = cate.CategoryName };

// 獲取LINQ轉換的SQL語句
string sql = innerJoin1.ToQueryString();

//2. 兩表聯合查詢 - 匿名示例
var innerJoin2 = from cate in _context.Set<Category>()
join prod in _context.Set<Product>() on cate.CategoryId equals prod.CategoryId
select new { Name = prod.ProductName, Category = cate.CategoryName };

//3. 三表聯合查詢 - 使用OrdersViewModel強類型
var innerJoin3 = from orders in _context.Orders.TagWith("3 Tables join")
join details in _context.OrderDetails on orders.OrderId equals details.OrderId
join prods in _context.Products on details.ProductId equals prods.ProductId
select new OrdersViewModel { 
    ProductId = details.ProductId, 
    ProductName = prods.ProductName, 
    OrderId = orders.OrderId, 
    UnitPrice = details.UnitPrice, 
    OrderDate = orders.OrderDate, 
    ShipAddress = orders.ShipAddress, 
    ShipCity = orders.ShipCity, 
    ShipCountry = orders.ShipCountry 
};

//4. 四表聯合查詢 - 匿名示例
var innerJoin4 = from customer in _context.Customers.TagWith("4 Tables join")
join order in _context.Orders on customer.CustomerId equals order.CustomerId
join details in _context.OrderDetails on order.OrderId equals details.OrderId
join prod in _context.Products on details.ProductId equals prod.ProductId
select new { 
    order.OrderId, 
    customer.CompanyName, 
    customer.ContactName, 
    details.ProductId, 
    prod.ProductName, 
    details.UnitPrice, 
    details.Quantity 
};

var result = await innerJoin4.ToListAsync();

return Json(result);

//string json = Newtonsoft.Json.JsonConvert.SerializeObject(result);
//return Content(json, "application/json");
}

❇️Skip與Take方法

public async Task<IActionResult> SkipTake()
{
    var products = from p in _context.Products
                   where p.UnitPrice >= 10 && p.UnitPrice <= 15
                   orderby p.ProductName descending, p.UnitPrice ascending
                   select p;

    // Skip(5) 跳過前 5 筆,然後 Take(10) 取 10 筆
    var query = await products.Skip(5).Take(10).ToListAsync();

    return View(query);
}

❇️IQuerable< T >與IEnumerable< T >與ToList()

public IActionResult QueryType()
{
    // 1. Lazy Loading 延後執行

    // 使用解析 Expression 將轉成實際呼叫的 SQL 語法,當回傳必要資料再執行查詢
    IQueryable<Product> products = _context.Products.TagWith("[Queryable]")
        .Where(p => p.UnitPrice > 10);
}
foreach (var i in products)
{
    Console.WriteLine($"{i.ProductId}, {i.ProductName}, {i.UnitPrice}, {i.UnitsInStock}");
}

// 2. 延遲加載:將資料全部取出之後再轉換成 IEnumerable 並進行篩選操作
IEnumerable<Product> prods = _context.Products.TagWith("[IEnumerable]")
    .AsEnumerable()
    .Where(p => p.UnitPrice > 20);

// 將篩選後的資料轉換為列表並逐一輸出
prods.ToList().ForEach(p => { Console.WriteLine($"{p.ProductId}, {p.ProductName}, {p.UnitPrice}, {p.UnitsInStock}"); });

// 3. 立即加載:將資料轉換成 List<T>,立即執行查詢並將結果載入到記憶體中
List<Product> prodList = _context.Products.TagWith("[ToList()]")
    .Where(p => p.UnitPrice > 30)
    .ToList();

// 4. 加載 OrderDetails 導覽屬性:同時取出每個產品的相關訂單明細資料
var pds = _context.Products
    .Where(p => p.UnitPrice > 40)
    .Include(p => p.OrderDetails)
    .ToList();

// 將列表轉換為 JSON,並設定避免參考循環的處理方式
JsonConvert.DefaultSettings = () => new JsonSerializerSettings
{
    ReferenceLoopHandling = ReferenceLoopHandling.Ignore
};

string json = JsonConvert.SerializeObject(pds);
return View(products);

❇️使用原生SQL查詢

❇️執行Update及Delete非查詢類的SQL語法

那麼以上就是今天的分享啦~
明天見啦~See YA(。•̀ᴗ-)


上一篇
Day26:設定第一個Entity Framework Core資料庫
下一篇
Day28:如何部署應用程式(IIS篇)
系列文
ASP.NET Core 30日成長路30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言